<script setup>
// components
import Select from '../Select/Select.vue'
import DatePicker from '../DatePicker/DatePicker.vue'
// others
import { toCssPx } from '@/utils/helper'
import { ref } from 'vue'

// props
defineProps({
  form: { type: Object, default: () => {} },
  config: { type: Array, default: () => [] },
  rules: { type: Object, default: () => {} },
  lableWidth: { type: String, default: '' },
  search: Boolean,
  loading: Boolean,
  width: { type: [Number, String], default: '220' }
})
const emit = defineEmits(['change', 'visibleChange', 'searchForm', 'resetForm'])
const formRef = ref()
const change = (value, prop, config) => {
  emit('change', { value, prop, config })
}
const visibleChange = (value, prop, config) => {
  emit('visibleChange', { value, prop, config })
}
// 搜索、重置按钮
const searchForm = () => {
  emit('searchForm')
}
const resetForm = () => {
  emit('resetForm')
}
</script>

<template>
  <el-form
    ref="formRef"
    :model="form"
    :label-width="lableWidth"
    :rules="rules"
    @submit.prevent
  >
    <el-row :gutter="20">
      <el-col
        v-for="configItem in config"
        :key="configItem.key"
        :span="configItem.span || 'auto'"
      >
        <el-form-item
          :label="configItem.label"
          :label-width="configItem.labelWidth"
          :prop="configItem.prop"
          :rules="configItem.rules"
        >
          <!-- text -->
          <template v-if="configItem.type === 'text'">
            <el-text :style="{ width: toCssPx(width) }">
              {{ form[configItem.prop] }}
            </el-text>
          </template>
          <!-- input -->
          <template v-if="configItem.type === 'input'">
            <el-input
              v-model.trim="form[configItem.prop]"
              :type="configItem.kind || 'input'"
              :placeholder="
                configItem.placeholder ||
                (configItem.label ? `请输入${configItem.label}` : '请输入')
              "
              :disabled="configItem.disabled"
              :clearable="configItem.clearable"
              :size="configItem.size"
              :formatter="configItem.formatter"
              :parser="configItem.parser"
              :show-password="configItem.showPassword"
              :suffix-icon="configItem.suffixIcon"
              :prefix-icon="configItem.prefixIcon"
              :autosize="configItem.autosize"
              :show-word-limit="configItem.showWordLimit"
              :minlength="configItem.minlength"
              :maxlength="configItem.maxlength"
              :readonly="configItem.readonly"
              :style="{ width: toCssPx(configItem.width) || toCssPx(width) }"
            ></el-input>
          </template>
          <!-- inputNumber -->
          <template v-if="configItem.type === 'inputNumber'">
            <el-input-number
              v-model.trim="form[configItem.prop]"
              :placeholder="
                configItem.placeholder ||
                (configItem.label ? `请输入${configItem.label}` : '请输入')
              "
              :disabled="configItem.disabled"
              :min="configItem.min"
              :max="configItem.max"
              :size="configItem.size"
              :controls="configItem.controls"
              :controls-position="configItem.controlsPosition"
              :step="configItem.step"
              :step-strictly="configItem.stepStrictly"
              :precision="configItem.precision"
              :style="{ width: toCssPx(configItem.width) || toCssPx(width) }"
            ></el-input-number>
          </template>
          <!-- select -->
          <template v-if="configItem.type === 'select'">
            <Select
              v-model="form[configItem.prop]"
              :options="configItem.options"
              :placeholder="
                configItem.placeholder ||
                (configItem.label ? `请选择${configItem.label}` : '请选择')
              "
              :size="configItem.size"
              :disabled="configItem.disabled"
              :clearable="configItem.clearable"
              :filterable="configItem.filterable"
              :multiple="configItem.multiple"
              :multiple-limit="configItem.multipleLimit"
              :collapse-tags="configItem.collapseTags"
              :collapse-tags-tooltip="configItem.collapseTagsToolTip"
              :max-collapse-tags="configItem.maxCollapseTags"
              :value-key="configItem.valueKey"
              :placement="configItem.placement"
              :is-enum="configItem.isEnum"
              :is-item="configItem.isItem"
              :popper-class="configItem.popperClass"
              :loading="configItem.loading"
              :loading-text="configItem.loadingText"
              :no-match-text="configItem.noMatchText"
              :no-data-text="configItem.noDataText"
              :remote="configItem.remote"
              :remote-method="configItem.remoteMethod"
              :style="{ width: toCssPx(configItem.width) || toCssPx(width) }"
              @change="(value) => change(value, configItem.prop, configItem)"
              @visible-change="
                value = visibleChange(value, configItem.prop, configItem)
              "
            />
          </template>
          <!-- radio -->
          <template v-if="configItem.type === 'radio'">
            <el-radio-group
              v-model="form[configItem.prop]"
              :disabled="configItem.disabled"
            >
              <el-radio
                v-for="(item, index) in configItem.options"
                :key="index"
                :label="item.value"
                @change="(value) => change(value, configItem.prop, configItem)"
              >
                {{ item.label }}
              </el-radio>
            </el-radio-group>
          </template>
          <!-- switch -->
          <template v-if="configItem.type === 'switch'">
            <el-switch
              v-model="form[configItem.prop]"
              :inline-prompt="configItem.inlinePrompt"
              :disabled="configItem.disabled"
              :active-color="configItem.activeColor"
              :active-text="configItem.activeText"
              :active-value="configItem.activeValue"
              :inactive-color="configItem.inactiveColor"
              :inactive-text="configItem.inactiveText"
              :inactive-value="configItem.inactiveValue"
              @change="(value) => change(value, configItem.prop, configItem)"
            />
          </template>
          <!-- date -->
          <template v-if="configItem.type === 'date'">
            <DatePicker
              v-model="form[configItem.prop]"
              :type="configItem.kind || 'date'"
              :placeholder="configItem.placeholder"
              :disabled-date="configItem.disabledDate"
              :shortcuts="configItem.shortcuts"
              :disabled="configItem.disabled"
              :size="configItem.size"
              :popper-class="configItem.popperClass"
              :editable="configItem.editable"
              :clearable="configItem.clearable"
              :style="{ width: toCssPx(configItem.width) || toCssPx(width) }"
              @change="(value) => change(value, configItem.prop, configItem)"
            />
          </template>
          <!-- form-item 插槽 -->
          <slot :config="configItem" :data="form" :name="configItem.slotName" />
        </el-form-item>
      </el-col>
      <!-- 全局插槽 -->
      <slot />
      <!-- 搜索 重置 -->
      <el-form-item label-width="0px">
        <!-- search -->
        <template v-if="search">
          <div class="form-sarch">
            <el-button
              v-loading="loading"
              type="primary"
              icon="Search"
              @click="searchForm"
            >
              搜索
            </el-button>
            <el-button v-loading="loading" icon="Refresh" @click="resetForm">
              重置
            </el-button>
          </div>
        </template>
      </el-form-item>
    </el-row>
  </el-form>
</template>

<style lang="less" scoped>
:deep(.el-form-item__content) {
  // inputNumber
  .el-input-number {
    &.is-without-controls .el-input__wrapper {
      padding-left: 11px;
      padding-right: 11px;
    }
  }
  // select
  .el-select {
    flex-grow: 1;
  }
  .form-sarch {
    display: flex;
    align-items: center;
    padding: 0 10px;
    .el-button {
      font-size: 14px;
    }
    .el-button--primary {
      background-color: #1890ff;
      border-color: #1890ff;
    }
  }
}
:deep(.el-form-item__label) {
  font-weight: normal;
}
:deep(.el-input__inner) {
  line-height: normal;
}
</style>
